package org.opens.apache.commonsNet;

import cn.hutool.core.util.StrUtil;
import org.apache.commons.net.telnet.TelnetClient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.SocketException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

/**
 * 功能描述
 *
 * @author: zhangyuming
 * @date: 2023/7/6 15:29
 */
public class TelnetHodler {

    private TelnetClient telnet;

    private InputStream inputStream;

    private OutputStream outputStream;

    private PrintStream printStream;

    private String ip;

    private int port;

    private String username;

    private String password;

    private AtomicBoolean connectFlag = new AtomicBoolean(false);

    private static final int DEFAULT_TELNET_PORT = 23;

    public TelnetHodler(String ip, int port, String username, String password) {
        this.ip = ip;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    public TelnetHodler(String ip, String username, String password) {
        this(ip, DEFAULT_TELNET_PORT, username, password);
    }

    public void connect() {
        if (connectFlag.get()) {
            return;
        }

        telnet = new TelnetClient("vt200");
        telnet.setDefaultTimeout(5000);

        try {
            telnet.connect(ip, port);
            telnet.setSoTimeout(5000);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        inputStream = telnet.getInputStream();
        outputStream = telnet.getOutputStream();

        printStream = new PrintStream(outputStream);

        read("login:");
        runCommand(username);
        read("Password:");
        runCommand(password);

        connectFlag.set(true);
    }

    public void close() throws IOException {
        printStream.println("exit");
        printStream.flush();
        if (printStream != null) {
            printStream.close();
        }
        if (outputStream != null) {
            outputStream.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        if (telnet != null) {
            telnet.disconnect();
        }
    }

    public String runCommand(String command, Consumer<String> listener) {
        printStream.println(command);
        printStream.flush();
        String readResult = read(null);
        if (listener != null) {
            listener.accept(readResult);
        }
        return readResult;
    }

    public String runCommand(String command) {
        return runCommand(command, null);
    }

    public String read(String pattern) {
        byte[] buffer = new byte[1024];
        int size = -1;
        StringBuilder result = new StringBuilder();
        try {
            while ((size = inputStream.read(buffer))!= -1) {
                result.append(new String(buffer, 0, size));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (StrUtil.isBlank(pattern)) {
            return result.toString();
        }

        String resultString = result.toString();
        String[] splitResult = resultString.split("\n");

        for (int i = 0; i < splitResult.length; i++) {
            if (splitResult[i].contains(pattern)) {
                return splitResult[i];
            }
        }

        return null;
    }

}
